#include "configxml.h"
#include <memory>
#include <unordered_map>
#include <mutex>
#include <string>
#include <algorithm>

#include "xmlhelper.h"

namespace{
    std::mutex g_mutex;
    std::unordered_map<int,std::shared_ptr<XmlHelper>>g_map;
    constexpr size_t BUF_LEN{4096};
    char g_buf[BUF_LEN]{};
}

#define DEF_LOCK std::lock_guard<std::mutex>loc(g_mutex)

namespace Bob{
int CreateInstance()
{
    DEF_LOCK;
    int id{0};
    while(g_map.find(id) != g_map.end())id++;
    g_map[id] = std::make_shared<XmlHelper>();
    return id;
}

void ReleaseInstance(int id)
{
    DEF_LOCK;
    g_map.erase(id);
}

auto GetXmlPrt(int id)->std::shared_ptr<XmlHelper>
{
    DEF_LOCK;
    while(g_map.find(id) != g_map.end())
        return g_map[id];
    return nullptr;
}



bool LoadFile(int id, const char *path)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->loadFile(path);
    return false;
}

bool SaveFile(int id, const char *path)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->saveFile(path);
    return false;
}

int ReadInt(int id, const char *key, int default_var)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->read(key,default_var);
    return -1;
}



double ReadDouble(int id, const char *key, double default_var)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->read(key,default_var);
    return -1.0f;
}

bool ReadBool(int id, const char *key, bool default_var)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->read(key,default_var);
    return false;
}

const char *ReadStr(int id, const char *key, const char *default_var)
{
    if(auto ptr = GetXmlPrt(id);ptr)
    {
        std::string temp = ptr->read(key,std::string(default_var));
        size_t size = std::min(temp.size(),BUF_LEN-1);
        std::memcpy(g_buf,temp.data(),size);
        g_buf[size]='\0';
        return g_buf;
    }
    return "";
}

bool WriteInt(int id, const char *key, int value)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->write(key,value);
    return false;
}



bool WriteDouble(int id, const char *key, double value)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->write(key,value);
    return false;
}

bool WriteBool(int id, const char *key, bool value)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->write(key,value);
    return false;
}

bool WriteStr(int id, const char *key, const char *value)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->write(key,std::string(value));
    return false;
}

void PrintDocument(int id)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        ptr->debugPrintDocument();
}

const char *GetDocumentStr(int id)
{
    if(auto ptr = GetXmlPrt(id);ptr)
    {
        std::string temp =  ptr->toString();
        auto size = std::min(temp.size(),BUF_LEN-1);
        std::memcpy(g_buf,temp.data(),size);
        g_buf[size]= '\0';
        return g_buf;
    }
    return "";
}

bool RemoveElement(int id, const char *key)
{
    if(auto ptr = GetXmlPrt(id);ptr)
        return ptr->remove(key);
    return false;
}

}//namespace Bob

